const crypto = require('crypto')
const config = require('../config')

class CryptoUtil {
  constructor() {
    this.algorithm = 'aes-256-gcm'
    this.keyLength = 32
    this.ivLength = 16
    this.tagLength = 16
    this.key = this.deriveKey(config.encryption.key)
  }

  /**
   * 从配置密钥派生加密密钥
   */
  deriveKey(password) {
    return crypto.scryptSync(password, 'salt', this.keyLength)
  }

  /**
   * 加密文本
   * @param {string} text - 要加密的文本
   * @returns {string} - 加密后的文本（base64编码）
   */
  encrypt(text) {
    try {
      const iv = crypto.randomBytes(this.ivLength)
      const cipher = crypto.createCipher(this.algorithm, this.key, { iv })
      
      let encrypted = cipher.update(text, 'utf8', 'hex')
      encrypted += cipher.final('hex')
      
      const tag = cipher.getAuthTag()
      
      // 组合 iv + tag + encrypted
      const combined = Buffer.concat([
        iv,
        tag,
        Buffer.from(encrypted, 'hex')
      ])
      
      return combined.toString('base64')
    } catch (error) {
      throw new Error(`加密失败: ${error.message}`)
    }
  }

  /**
   * 解密文本
   * @param {string} encryptedText - 加密的文本（base64编码）
   * @returns {string} - 解密后的文本
   */
  decrypt(encryptedText) {
    try {
      const combined = Buffer.from(encryptedText, 'base64')
      
      // 提取 iv, tag, encrypted
      const iv = combined.slice(0, this.ivLength)
      const tag = combined.slice(this.ivLength, this.ivLength + this.tagLength)
      const encrypted = combined.slice(this.ivLength + this.tagLength)
      
      const decipher = crypto.createDecipher(this.algorithm, this.key, { iv })
      decipher.setAuthTag(tag)
      
      let decrypted = decipher.update(encrypted, null, 'utf8')
      decrypted += decipher.final('utf8')
      
      return decrypted
    } catch (error) {
      throw new Error(`解密失败: ${error.message}`)
    }
  }

  /**
   * 生成随机字符串
   * @param {number} length - 字符串长度
   * @returns {string} - 随机字符串
   */
  generateRandomString(length = 32) {
    return crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length)
  }

  /**
   * 生成UUID
   * @returns {string} - UUID
   */
  generateUUID() {
    return crypto.randomUUID()
  }

  /**
   * 计算文本的哈希值
   * @param {string} text - 要计算哈希的文本
   * @param {string} algorithm - 哈希算法，默认sha256
   * @returns {string} - 哈希值
   */
  hash(text, algorithm = 'sha256') {
    return crypto.createHash(algorithm).update(text).digest('hex')
  }
}

module.exports = new CryptoUtil()